package com.yanlin.apidriver.service;

import com.yanlin.apidriver.remote.ServiceDriverUserClient;
import com.yanlin.apidriver.remote.ServiceVerificationCodeClient;
import com.yanlin.internalcommon.dto.ResponseResult;
import com.yanlin.internalcommon.response.DriverUserExistsResponse;
import com.yanlin.internalcommon.response.NumberCodeResponse;
import com.yanlin.internalcommon.response.TokenResponse;
import com.yanlin.internalcommon.util.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import static com.yanlin.internalcommon.constant.CommonStatusEnum.DRIVER_NOT_EXISTS;
import static com.yanlin.internalcommon.constant.CommonStatusEnum.VERIFICATION_CODE_ERROR;
import static com.yanlin.internalcommon.constant.IdentityConstant.DRIVER_PHONE;
import static com.yanlin.internalcommon.constant.TokenConstant.ACCESS_TOKEN_TYPE;
import static com.yanlin.internalcommon.constant.TokenConstant.REFRESH_TOKEN_TYPE;
import static com.yanlin.internalcommon.util.RedisPrefixUtil.*;
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.MINUTES;

/**
 * <p>标题：ServiceVerificationCodeService</p>
 * <p>功能：</p>
 * <p>
 * 其他说明：
 * </p>
 * <p>审核：</p>
 * <p>重构：</p>
 * <p>创建日期：2025-06-15 17:45</p>
 *
 * @author yanlin
 */
@Service
@Slf4j
public class VerificationCodeService {

    @Autowired
    private ServiceDriverUserClient serviceDriverUserClient;
    @Autowired
    private ServiceVerificationCodeClient serviceVerificationCodeClient;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public ResponseResult checkAndSendVerificationCode(String driverPhone) {
        // 查询service-driver-user服务，该手机号是否已存在
        ResponseResult<DriverUserExistsResponse> result =
                serviceDriverUserClient.checkDriver(driverPhone);
        DriverUserExistsResponse driverUserView = result.getData();
        int ifExists = driverUserView.getIfExists();
        if (ifExists == 0) {
            log.debug("根据司机手机号查询信息==不存在");
            return ResponseResult.fail(
                    DRIVER_NOT_EXISTS.getCode(),
                    DRIVER_NOT_EXISTS.getValue());
        }
        log.debug("根据司机手机号查询信息==存在");

        // 获取验证码
        //调用验证码服务
        ResponseResult<NumberCodeResponse> numberCodeResponse =
                serviceVerificationCodeClient.getNumberCode(6);
        int numberCode = numberCodeResponse.getData().getNumberCode();
        log.debug("根据司机手机号获取验证码：{}", numberCode);

        // 调用第三方发送验证码

        // 生成key存入redis
        String verificationCodeKey = getVerificationCodeKey(driverPhone, DRIVER_PHONE);
        stringRedisTemplate.opsForValue().set(
                verificationCodeKey, String.valueOf(numberCode), VERIFICATION_CODE_EXPIRATION, MINUTES);
        return ResponseResult.success(numberCode);
    }

    /**
     * 校验验证码
     * @param driverPhone 手机号
     * @param verificationCode 验证码
     * @return
     */
    public ResponseResult checkCode(String driverPhone, String verificationCode) {
        // 根据手机号，去redis读取验证码
        String verificationCodeKey = getVerificationCodeKey(driverPhone, DRIVER_PHONE);
        String redisCode = stringRedisTemplate.opsForValue().get(verificationCodeKey);

        // 校验验证码
        if (StringUtils.isBlank(redisCode) || !verificationCode.equals(redisCode)) {
            return ResponseResult.fail(
                    VERIFICATION_CODE_ERROR.getCode(),
                    VERIFICATION_CODE_ERROR.getValue());

        }

        // 颁发令牌
        String accessToken = JwtUtils.generateToken(driverPhone, DRIVER_PHONE, ACCESS_TOKEN_TYPE);
        String refreshToken = JwtUtils.generateToken(driverPhone, DRIVER_PHONE, REFRESH_TOKEN_TYPE);
        // 令牌存放在redis中
        String accessTokenKey = getTokenKey(driverPhone, DRIVER_PHONE, ACCESS_TOKEN_TYPE);
        String refreshTokenKey = getTokenKey(driverPhone, DRIVER_PHONE, REFRESH_TOKEN_TYPE);
        stringRedisTemplate.opsForValue().set(accessTokenKey, accessToken, ACCESS_TOKEN_EXPIRATINO, DAYS);
        stringRedisTemplate.opsForValue().set(refreshTokenKey, refreshToken, REFRESH_TOKEN_EXPIRATINO, DAYS);
        /*stringRedisTemplate.opsForValue().set(accessTokenKey, accessToken, 30, TimeUnit.SECONDS);
        stringRedisTemplate.opsForValue().set(refreshTokenKey, refreshToken, 120, TimeUnit.SECONDS);*/

        TokenResponse tokenResponse = new TokenResponse();
        tokenResponse.setAccessToken(accessToken);
        tokenResponse.setRefreshToken(refreshToken);
        return ResponseResult.success(tokenResponse);
    }
}